
obj/bootblock.o:     file format elf32-i386


Disassembly of section .text:

00007c00 <start>:
.set SMAP,					0x534d4150

.globl start
start:
.code16												# Assemble for 16-bit mode
	cli												# Disable interrupts
    7c00:	fa                   	cli    
	cld												# String operations increment
    7c01:	fc                   	cld    

	# Set up the important data segment registers (DS, ES, SS).
	xorw %ax, %ax									# Segment number zero
    7c02:	31 c0                	xor    %eax,%eax
	movw %ax, %ds									# -> Data Segment
    7c04:	8e d8                	mov    %eax,%ds
	movw %ax, %es									# -> Extra Segment
    7c06:	8e c0                	mov    %eax,%es
	movw %ax, %ss									# -> Stack Segment
    7c08:	8e d0                	mov    %eax,%ss

00007c0a <seta20.1>:
	# Enable A20:
	#  For backwards compatibility with the earliest PCs, physical
	#  address line 20 is tied low, so that addresses higher than
	#  1MB wrap around to zero by default. This code undoes this.
seta20.1:
	inb $0x64, %al									# Wait for not busy
    7c0a:	e4 64                	in     $0x64,%al
	testb $0x2, %al
    7c0c:	a8 02                	test   $0x2,%al
	jnz seta20.1
    7c0e:	75 fa                	jne    7c0a <seta20.1>

	movb $0xd1, %al									# 0xd1 -> port 0x64
    7c10:	b0 d1                	mov    $0xd1,%al
	outb %al, $0x64
    7c12:	e6 64                	out    %al,$0x64

00007c14 <seta20.2>:

seta20.2:
	inb $0x64, %al									# Wait for not busy
    7c14:	e4 64                	in     $0x64,%al
	testb $0x2, %al
    7c16:	a8 02                	test   $0x2,%al
	jnz seta20.2
    7c18:	75 fa                	jne    7c14 <seta20.2>

	movb $0xdf, %al									# 0xdf -> port 0x60
    7c1a:	b0 df                	mov    $0xdf,%al
	outb %al, $0x60
    7c1c:	e6 60                	out    %al,$0x60

00007c1e <probe_memory>:

probe_memory:
	movl $0, 0x8000
    7c1e:	66 c7 06 00 80       	movw   $0x8000,(%esi)
    7c23:	00 00                	add    %al,(%eax)
    7c25:	00 00                	add    %al,(%eax)
	xorl %ebx, %ebx
    7c27:	66 31 db             	xor    %bx,%bx
	movw $0x8004, %di
    7c2a:	bf 04 80 66 b8       	mov    $0xb8668004,%edi

00007c2d <start_probe>:
start_probe:
	movl $0xE820, %eax
    7c2d:	66 b8 20 e8          	mov    $0xe820,%ax
    7c31:	00 00                	add    %al,(%eax)
	movl $20, %ecx
    7c33:	66 b9 14 00          	mov    $0x14,%cx
    7c37:	00 00                	add    %al,(%eax)
	movl $SMAP, %edx
    7c39:	66 ba 50 41          	mov    $0x4150,%dx
    7c3d:	4d                   	dec    %ebp
    7c3e:	53                   	push   %ebx
	int $0x15
    7c3f:	cd 15                	int    $0x15
	jnc cont
    7c41:	73 08                	jae    7c4b <cont>
	movw $12345, 0x8000
    7c43:	c7 06 00 80 39 30    	movl   $0x30398000,(%esi)
	jmp finish_probe
    7c49:	eb 0e                	jmp    7c59 <finish_probe>

00007c4b <cont>:
cont:
	addw $20, %di
    7c4b:	83 c7 14             	add    $0x14,%edi
	incl 0x8000
    7c4e:	66 ff 06             	incw   (%esi)
    7c51:	00 80 66 83 fb 00    	add    %al,0xfb8366(%eax)
	cmpl $0, %ebx
	jnz start_probe
    7c57:	75 d4                	jne    7c2d <start_probe>

00007c59 <finish_probe>:

	# Switch from real to protected mode, using a bootstrap GDT
	# and segment translation that makes virtual addresses
	# identical to physical addresses, so that the
	# effective memory map does not change during the switch.
	lgdt gdtdesc
    7c59:	0f 01 16             	lgdtl  (%esi)
    7c5c:	a4                   	movsb  %ds:(%esi),%es:(%edi)
    7c5d:	7c 0f                	jl     7c6e <protcseg+0x1>
	movl %cr0, %eax
    7c5f:	20 c0                	and    %al,%al
	orl $CR0_PE_ON, %eax
    7c61:	66 83 c8 01          	or     $0x1,%ax
	movl %eax, %cr0
    7c65:	0f 22 c0             	mov    %eax,%cr0

	# Jump to next instruction, but in 32-bit code segment.
	# Switches processor into 32-bit mode.
	ljmp $PROT_MODE_CSEG, $protcseg
    7c68:	ea 6d 7c 08 00 66 b8 	ljmp   $0xb866,$0x87c6d

00007c6d <protcseg>:

.code32												# Assemble for 32-bit mode
protcseg:
	# Set up the protected-mode data segment registers
	movw $PROT_MODE_DSEG, %ax						# Our data segment selector
    7c6d:	66 b8 10 00          	mov    $0x10,%ax
	movw %ax, %ds									# -> DS: Data Segment
    7c71:	8e d8                	mov    %eax,%ds
	movw %ax, %es									# -> ES: Extra Segment
    7c73:	8e c0                	mov    %eax,%es
	movw %ax, %fs									# -> FS
    7c75:	8e e0                	mov    %eax,%fs
	movw %ax, %gs									# -> GS
    7c77:	8e e8                	mov    %eax,%gs
	movw %ax, %ss									# -> SS: Stack Segment
    7c79:	8e d0                	mov    %eax,%ss

	# Set up the stack pointer and call into C.
	movl $0x0, %ebp
    7c7b:	bd 00 00 00 00       	mov    $0x0,%ebp
	movl $start, %esp
    7c80:	bc 00 7c 00 00       	mov    $0x7c00,%esp
	call bootmain
    7c85:	e8 b4 00 00 00       	call   7d3e <bootmain>

00007c8a <spin>:

	# If bootmain returns (it shouldn't), loop.
spin:
	jmp spin
    7c8a:	eb fe                	jmp    7c8a <spin>

00007c8c <gdt>:
	...
    7c94:	ff                   	(bad)  
    7c95:	ff 00                	incl   (%eax)
    7c97:	00 00                	add    %al,(%eax)
    7c99:	9a cf 00 ff ff 00 00 	lcall  $0x0,$0xffff00cf
    7ca0:	00 92 cf 00 17 00    	add    %dl,0x1700cf(%edx)

00007ca4 <gdtdesc>:
    7ca4:	17                   	pop    %ss
    7ca5:	00 8c 7c 00 00 90 90 	add    %cl,-0x6f700000(%esp,%edi,2)

00007cac <waitdisk>:
#define SECTSIZE		512
#define ELFHDR			((struct elfhdr *)0x10000)		// scratch space

/* waitdisk - wait for disk ready */
static void
waitdisk(void) {
    7cac:	55                   	push   %ebp
static inline void invlpg(void *addr) __attribute__((always_inline));

static inline uint8_t
inb(uint16_t port) {
	uint8_t data;
	asm volatile ("inb %1, %0" : "=a" (data) : "d" (port));
    7cad:	ba f7 01 00 00       	mov    $0x1f7,%edx
    7cb2:	89 e5                	mov    %esp,%ebp
    7cb4:	ec                   	in     (%dx),%al
	while ((inb(0x1F7) & 0xC0) != 0x40)
    7cb5:	25 c0 00 00 00       	and    $0xc0,%eax
    7cba:	83 f8 40             	cmp    $0x40,%eax
    7cbd:	75 f5                	jne    7cb4 <waitdisk+0x8>
		/* do nothing */;
}
    7cbf:	5d                   	pop    %ebp
    7cc0:	c3                   	ret    

00007cc1 <readseg>:
/* *
 * readseg - read @count bytes at @offset from kernel into virtual address @va,
 * might copy more than asked.
 * */
static void
readseg(uintptr_t va, uint32_t count, uint32_t offset) {
    7cc1:	55                   	push   %ebp
	uintptr_t end_va = va + count;
    7cc2:	01 c2                	add    %eax,%edx
/* *
 * readseg - read @count bytes at @offset from kernel into virtual address @va,
 * might copy more than asked.
 * */
static void
readseg(uintptr_t va, uint32_t count, uint32_t offset) {
    7cc4:	89 e5                	mov    %esp,%ebp
    7cc6:	57                   	push   %edi
    7cc7:	56                   	push   %esi
	uintptr_t end_va = va + count;

	// round down to sector boundary
	va -= offset % SECTSIZE;
    7cc8:	89 c6                	mov    %eax,%esi
/* *
 * readseg - read @count bytes at @offset from kernel into virtual address @va,
 * might copy more than asked.
 * */
static void
readseg(uintptr_t va, uint32_t count, uint32_t offset) {
    7cca:	53                   	push   %ebx
    7ccb:	83 ec 04             	sub    $0x4,%esp
	uintptr_t end_va = va + count;
    7cce:	89 55 f0             	mov    %edx,-0x10(%ebp)

	// round down to sector boundary
	va -= offset % SECTSIZE;
    7cd1:	89 ca                	mov    %ecx,%edx
    7cd3:	81 e2 ff 01 00 00    	and    $0x1ff,%edx

	// translate from bytes to sectors; kernel starts at sector 1
	uint32_t secno = (offset / SECTSIZE) + 1;
    7cd9:	c1 e9 09             	shr    $0x9,%ecx
static void
readseg(uintptr_t va, uint32_t count, uint32_t offset) {
	uintptr_t end_va = va + count;

	// round down to sector boundary
	va -= offset % SECTSIZE;
    7cdc:	29 d6                	sub    %edx,%esi

	// translate from bytes to sectors; kernel starts at sector 1
	uint32_t secno = (offset / SECTSIZE) + 1;
    7cde:	8d 59 01             	lea    0x1(%ecx),%ebx

	// If this is too slow, we could read lots of sectors at a time.
	// We'd write more to memory than asked, but it doesn't matter --
	// we load in increasing order.
	for (; va < end_va; va += SECTSIZE, secno ++) {
    7ce1:	eb 50                	jmp    7d33 <readseg+0x72>

/* readsect - read a single sector at @secno into @dst */
static void
readsect(void *dst, uint32_t secno) {
	// wait for disk to be ready
	waitdisk();
    7ce3:	e8 c4 ff ff ff       	call   7cac <waitdisk>
			: "memory", "cc");
}

static inline void
outb(uint16_t port, uint8_t data) {
	asm volatile ("outb %0, %1" :: "a" (data), "d" (port));
    7ce8:	b0 01                	mov    $0x1,%al
    7cea:	ba f2 01 00 00       	mov    $0x1f2,%edx
    7cef:	ee                   	out    %al,(%dx)
    7cf0:	b2 f3                	mov    $0xf3,%dl
    7cf2:	88 d8                	mov    %bl,%al
    7cf4:	ee                   	out    %al,(%dx)

	outb(0x1F2, 1);							// count = 1
	outb(0x1F3, secno & 0xFF);
	outb(0x1F4, (secno >> 8) & 0xFF);
    7cf5:	89 d8                	mov    %ebx,%eax
    7cf7:	b2 f4                	mov    $0xf4,%dl
    7cf9:	c1 e8 08             	shr    $0x8,%eax
    7cfc:	ee                   	out    %al,(%dx)
	outb(0x1F5, (secno >> 16) & 0xFF);
    7cfd:	89 d8                	mov    %ebx,%eax
    7cff:	b2 f5                	mov    $0xf5,%dl
    7d01:	c1 e8 10             	shr    $0x10,%eax
    7d04:	ee                   	out    %al,(%dx)
	outb(0x1F6, ((secno >> 24) & 0xF) | 0xE0);
    7d05:	89 d8                	mov    %ebx,%eax
    7d07:	b2 f6                	mov    $0xf6,%dl
    7d09:	c1 e8 18             	shr    $0x18,%eax
    7d0c:	83 e0 0f             	and    $0xf,%eax
    7d0f:	83 c8 e0             	or     $0xffffffe0,%eax
    7d12:	ee                   	out    %al,(%dx)
    7d13:	b0 20                	mov    $0x20,%al
    7d15:	b2 f7                	mov    $0xf7,%dl
    7d17:	ee                   	out    %al,(%dx)
	outb(0x1F7, 0x20);						// cmd 0x20 - read sectors

	// wait for disk to be ready
	waitdisk();
    7d18:	e8 8f ff ff ff       	call   7cac <waitdisk>
	return data;
}

static inline void
insl(uint32_t port, void *addr, int cnt) {
	asm volatile (
    7d1d:	89 f7                	mov    %esi,%edi
    7d1f:	b9 80 00 00 00       	mov    $0x80,%ecx
    7d24:	ba f0 01 00 00       	mov    $0x1f0,%edx
    7d29:	fc                   	cld    
    7d2a:	f2 6d                	repnz insl (%dx),%es:(%edi)
	uint32_t secno = (offset / SECTSIZE) + 1;

	// If this is too slow, we could read lots of sectors at a time.
	// We'd write more to memory than asked, but it doesn't matter --
	// we load in increasing order.
	for (; va < end_va; va += SECTSIZE, secno ++) {
    7d2c:	81 c6 00 02 00 00    	add    $0x200,%esi
    7d32:	43                   	inc    %ebx
    7d33:	3b 75 f0             	cmp    -0x10(%ebp),%esi
    7d36:	72 ab                	jb     7ce3 <readseg+0x22>
		readsect((void *)va, secno);
	}
}
    7d38:	58                   	pop    %eax
    7d39:	5b                   	pop    %ebx
    7d3a:	5e                   	pop    %esi
    7d3b:	5f                   	pop    %edi
    7d3c:	5d                   	pop    %ebp
    7d3d:	c3                   	ret    

00007d3e <bootmain>:

/* bootmain - the entry of bootloader */
void
bootmain(void) {
    7d3e:	55                   	push   %ebp
	// read the 1st page off disk
	readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0);
    7d3f:	31 c9                	xor    %ecx,%ecx
	}
}

/* bootmain - the entry of bootloader */
void
bootmain(void) {
    7d41:	89 e5                	mov    %esp,%ebp
	// read the 1st page off disk
	readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0);
    7d43:	ba 00 10 00 00       	mov    $0x1000,%edx
	}
}

/* bootmain - the entry of bootloader */
void
bootmain(void) {
    7d48:	56                   	push   %esi
	// read the 1st page off disk
	readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0);
    7d49:	b8 00 00 01 00       	mov    $0x10000,%eax
	}
}

/* bootmain - the entry of bootloader */
void
bootmain(void) {
    7d4e:	53                   	push   %ebx
	// read the 1st page off disk
	readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0);
    7d4f:	e8 6d ff ff ff       	call   7cc1 <readseg>

	// is this a valid ELF?
	if (ELFHDR->e_magic != ELF_MAGIC) {
    7d54:	81 3d 00 00 01 00 7f 	cmpl   $0x464c457f,0x10000
    7d5b:	45 4c 46 
    7d5e:	75 41                	jne    7da1 <bootmain+0x63>
	}

	struct proghdr *ph, *eph;

	// load each program segment (ignores ph flags)
	ph = (struct proghdr *)((uintptr_t)ELFHDR + ELFHDR->e_phoff);
    7d60:	8b 1d 1c 00 01 00    	mov    0x1001c,%ebx
	eph = ph + ELFHDR->e_phnum;
    7d66:	0f b7 35 2c 00 01 00 	movzwl 0x1002c,%esi
	}

	struct proghdr *ph, *eph;

	// load each program segment (ignores ph flags)
	ph = (struct proghdr *)((uintptr_t)ELFHDR + ELFHDR->e_phoff);
    7d6d:	81 c3 00 00 01 00    	add    $0x10000,%ebx
	eph = ph + ELFHDR->e_phnum;
    7d73:	c1 e6 05             	shl    $0x5,%esi
    7d76:	8d 34 33             	lea    (%ebx,%esi,1),%esi
	for (; ph < eph; ph ++) {
    7d79:	eb 16                	jmp    7d91 <bootmain+0x53>
		readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset);
    7d7b:	8b 43 08             	mov    0x8(%ebx),%eax
    7d7e:	8b 4b 04             	mov    0x4(%ebx),%ecx
    7d81:	8b 53 14             	mov    0x14(%ebx),%edx
	struct proghdr *ph, *eph;

	// load each program segment (ignores ph flags)
	ph = (struct proghdr *)((uintptr_t)ELFHDR + ELFHDR->e_phoff);
	eph = ph + ELFHDR->e_phnum;
	for (; ph < eph; ph ++) {
    7d84:	83 c3 20             	add    $0x20,%ebx
		readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset);
    7d87:	25 ff ff ff 00       	and    $0xffffff,%eax
    7d8c:	e8 30 ff ff ff       	call   7cc1 <readseg>
	struct proghdr *ph, *eph;

	// load each program segment (ignores ph flags)
	ph = (struct proghdr *)((uintptr_t)ELFHDR + ELFHDR->e_phoff);
	eph = ph + ELFHDR->e_phnum;
	for (; ph < eph; ph ++) {
    7d91:	39 f3                	cmp    %esi,%ebx
    7d93:	72 e6                	jb     7d7b <bootmain+0x3d>
		readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset);
	}

	// call the entry point from the ELF header
	// note: does not return
	((void (*)(void))(ELFHDR->e_entry & 0xFFFFFF))();
    7d95:	a1 18 00 01 00       	mov    0x10018,%eax
    7d9a:	25 ff ff ff 00       	and    $0xffffff,%eax
    7d9f:	ff d0                	call   *%eax
	asm volatile ("outb %0, %1" :: "a" (data), "d" (port));
}

static inline void
outw(uint16_t port, uint16_t data) {
	asm volatile ("outw %0, %1" :: "a" (data), "d" (port));
    7da1:	ba 00 8a ff ff       	mov    $0xffff8a00,%edx
    7da6:	89 d0                	mov    %edx,%eax
    7da8:	66 ef                	out    %ax,(%dx)
    7daa:	b8 00 8e ff ff       	mov    $0xffff8e00,%eax
    7daf:	66 ef                	out    %ax,(%dx)
    7db1:	eb fe                	jmp    7db1 <bootmain+0x73>
